package dreher;

import processing.core.PApplet;
import processing.core.PVector;

public class GridLine {
	private Dreher parent;
	
	  float[][] p00, p01, p02, p10, p11, p12, p13, p14, p15, p20, p21, p22, p23, p30, p31, p32; ////plane-point coordinates for all beamers and shapes
	  float[][] sp00, sp01, sp02, sp10, sp11, sp12, sp13, sp14, sp15, sp20, sp21, sp22, sp23, sp30, sp31, sp32; ////virtual space-point coordinates for all beamers and shapes - for transformation purposes
	  float[][] sp00d, sp01d, sp02d, sp10d, sp11d, sp12d, sp13d, sp14d, sp15d, sp20d, sp21d, sp22d, sp23d, sp30d, sp31d, sp32d; ////display coordinates
	  float[] points;
	  float[] pointsInSpace;
	  float xMin, xMax, yMin, yMax, zMin, zMax;
	  float planeValue;
	  int plane;
	  PVector[] set0_Point, set1_Point, set2_Point, set3_Point;
	  PVector[] set0_Vec, set1_Vec, set2_Vec, set3_Vec;
	  int[] set0_Shape, set1_Shape, set2_Shape, set3_Shape;
	  float transX, transY, transZ;
	  float rotX, rotY, rotZ;
	  float[][] transMatrix, invTransMatrix;
	  float[][] rotXMatrix, invRotXMatrix ;
	  float[][] rotYMatrix, invRotYMatrix;
	  float[][] rotZMatrix,  invRotZMatrix;
	  GridCoordinates gc_0, gc_1, gc_2, gc_3;

	  public GridLine (Dreher p, float thePlaneValue, char thePlaneName) {
		  parent = p;
	    planeValue = thePlaneValue;
	    setPlane(thePlaneName);
	    setBoundaries ();
	    setPointArrays();  
	    setLines();
	    transMatrix = new float[4][4];
	    rotXMatrix = new float[4][4];
	    rotYMatrix = new float[4][4];
	    rotZMatrix = new float[4][4];
	    
	   
	  };
	  
	  public void trans(float theX, float theY, float theZ) {
	    transX = theX;
	    transY = theY;
	    transZ = theZ;
	    setMatrices();
	    applyMatrices(transMatrix);
	    resetArrays();
	    setLines();
	  }
	  
	  public void rot(float theX, float theY, float theZ) {
	    rotX = theX;
	    rotY = theY;
	    rotZ = theZ;
	    setMatrices();
	    applyMatrices();
	    resetArrays();
	    setLines();
	  }

	  public void rotX(float theX) {
	    rotX = theX;
	    setMatrices();
	    applyMatrices(rotXMatrix);
	    resetArrays();
	    setLines();
//	    applyInvMatrices(invRotXMatrix);
	  }
	  
	    public void rotY(float theY) {
	    rotY = theY;
	    setMatrices();
	    applyMatrices(rotYMatrix);
	    resetArrays();
	    setLines();
	 //   applyInvMatrices(invRotYMatrix);
	  }
	  
	    
	 public void rotZ(float theZ) {
	    rotZ = theZ;
	    setMatrices();
	    applyMatrices(rotZMatrix);
	    resetArrays();
	    setLines();
	   // applyInvMatrices(invRotZMatrix);
	  }

	  
	  public void resetTransformations() {
	    transX = 0f;
	    transY = 0f;
	    transZ = 0f;
	    rotX = 0f;
	    rotY = 0f;
	    rotZ = 0f;
	    setMatrices();
	    setPointArrays();
	    resetArrays();
	    setLines();
	   }
	  
	  public void setMatrices() {

	 //   float[][] transMatrix = {{1,0,0,transX},{0,1,0,transY},{0,0,1,transZ},{0,0,0,1}};
//	    float[][] rotXMatrix = {{1,0,0,0},{0,cos(rotX),-sin(rotX),0},{0,sin(rotX),cos(rotX),0},{0,0,0,1}};  
//	    float[][] rotYMatrix = {{cos(rotY),0,sin(rotY),0},{0,1,0,0},{-sin(rotY),0,cos(rotY),0},{0,0,0,1}};
//	    float[][] rotZMatrix = {{cos(rotZ),-sin(rotZ),0,0},{sin(rotZ),cos(rotZ),0,0},{0,0,1,0},{0,0,0,1}};
	    transMatrix[0][0] = 1f;
	    transMatrix[0][1] = 0f;
	    transMatrix[0][2] = 0f;
	    transMatrix[0][3] = transX;
	    transMatrix[1][0] = 0f;
	    transMatrix[1][1] = 1f;
	    transMatrix[1][2] = 0f;
	    transMatrix[1][3] = transY;
	    transMatrix[2][0] = 0f;
	    transMatrix[2][1] = 0f;
	    transMatrix[2][2] = 1f;
	    transMatrix[2][3] = transZ;
	    transMatrix[3][0] = 0f;
	    transMatrix[3][1] = 0f;
	    transMatrix[3][2] = 0f;
	    transMatrix[3][3] = 1f;
	    
	    invTransMatrix = inverseMatrix4D(transMatrix);
	    
	    rotXMatrix[0][0] = 1;
	    rotXMatrix[0][1] = 0;
	    rotXMatrix[0][2] = 0;
	    rotXMatrix[0][3] = 0;
	    rotXMatrix[1][0] = 0;
	    rotXMatrix[1][1] = PApplet.cos(rotX);
	    rotXMatrix[1][2] = -PApplet.sin(rotX);
	    rotXMatrix[1][3] = 0;
	    rotXMatrix[2][0] = 0;
	    rotXMatrix[2][1] = PApplet.sin(rotX);
	    rotXMatrix[2][2] = PApplet.cos(rotX);
	    rotXMatrix[2][3] = 0;
	    rotXMatrix[3][0] = 0;
	    rotXMatrix[3][1] = 0;
	    rotXMatrix[3][2] = 0;
	    rotXMatrix[3][3] = 1;
	    
	    invRotXMatrix = inverseMatrix4D(rotXMatrix);
	    
	    rotYMatrix[0][0] = PApplet.cos(rotY);
	    rotYMatrix[0][1] = 0;
	    rotYMatrix[0][2] = PApplet.sin(rotY);
	    rotYMatrix[0][3] = 0;
	    rotYMatrix[1][0] = 0;
	    rotYMatrix[1][1] = 1;
	    rotYMatrix[1][2] = 0;
	    rotYMatrix[1][3] = 0;
	    rotYMatrix[2][0] = -PApplet.sin(rotY);
	    rotYMatrix[2][1] = 0;
	    rotYMatrix[2][2] = PApplet.cos(rotY);
	    rotYMatrix[2][3] = 0;
	    rotYMatrix[3][0] = 0;
	    rotYMatrix[3][1] = 0;
	    rotYMatrix[3][2] = 0;
	    rotYMatrix[3][3] = 1;
	    
	    invRotYMatrix = inverseMatrix4D(rotYMatrix);    
	    
	    rotZMatrix[0][0] = PApplet.cos(rotZ);
	    rotZMatrix[0][1] = -PApplet.sin(rotZ);
	    rotZMatrix[0][2] = 0;
	    rotZMatrix[0][3] = 0;
	    rotZMatrix[1][0] = PApplet.sin(rotZ);
	    rotZMatrix[1][1] = PApplet.cos(rotZ);
	    rotZMatrix[1][2] = 0;
	    rotZMatrix[1][3] = 0;
	    rotZMatrix[2][0] = 0;
	    rotZMatrix[2][1] = 0;
	    rotZMatrix[2][2] = 1;
	    rotZMatrix[2][3] = 0;
	    rotZMatrix[3][0] = 0;
	    rotZMatrix[3][1] = 0;
	    rotZMatrix[3][2] = 0;
	    rotZMatrix[3][3] = 1;
	    
	    invRotZMatrix = inverseMatrix4D(rotZMatrix);
	    
	  }

	  public void applyMatrices() {
	    matrixMultArray(sp00);
	    matrixMultArray(sp01);
	    matrixMultArray(sp02);
	    matrixMultArray(sp10);
	    matrixMultArray(sp11);
	    matrixMultArray(sp12);
	    matrixMultArray(sp13);
	    matrixMultArray(sp14);
	    matrixMultArray(sp15);
	    matrixMultArray(sp20);
	    matrixMultArray(sp21);
	    matrixMultArray(sp22);
	    matrixMultArray(sp23);
	    matrixMultArray(sp30);
	    matrixMultArray(sp31);
	    matrixMultArray(sp32);
	  }
	  
	  public void applyMatrices(float[][] m) {
	    matrixMultArray(sp00,m);
	    matrixMultArray(sp01,m);
	    matrixMultArray(sp02,m);
	    matrixMultArray(sp10,m);
	    matrixMultArray(sp11,m);
	    matrixMultArray(sp12,m);
	    matrixMultArray(sp13,m);
	    matrixMultArray(sp14,m);
	    matrixMultArray(sp15,m);
	    matrixMultArray(sp20,m);
	    matrixMultArray(sp21,m);
	    matrixMultArray(sp22,m);
	    matrixMultArray(sp23,m);
	    matrixMultArray(sp30,m);
	    matrixMultArray(sp31,m);
	    matrixMultArray(sp32,m);
	  }
	  
	//  void applyInvMatrices(float[][] m) {
//	    matrixMultArray(set0_Vec,m);
//	    matrixMultArray(set1_Vec,m);
//	    matrixMultArray(set2_Vec,m);
//	    matrixMultArray(set3_Vec,m);
	//  }
	  
	  
	  
	  ////works only with 4D-Matrices!
	  public float determinant4D(float[][] m)  {
	      float value;
	      value = m[0][3] * m[1][2] * m[2][1] * m[3][0]-m[0][2] * m[1][3] * m[2][1] * m[3][0]-m[0][3] * m[1][1] * m[2][2] * m[3][0]+m[0][1] * m[1][3] * m[2][2] * m[3][0]+
	      m[0][2] * m[1][1] * m[2][3] * m[3][0]-m[0][1] * m[1][2] * m[2][3] * m[3][0]-m[0][3] * m[1][2] * m[2][0] * m[3][1]+m[0][2] * m[1][3] * m[2][0] * m[3][1]+
	      m[0][3] * m[1][0] * m[2][2] * m[3][1]-m[0][0] * m[1][3] * m[2][2] * m[3][1]-m[0][2] * m[1][0] * m[2][3] * m[3][1]+m[0][0] * m[1][2] * m[2][3] * m[3][1]+
	      m[0][3] * m[1][1] * m[2][0] * m[3][2]-m[0][1] * m[1][3] * m[2][0] * m[3][2]-m[0][3] * m[1][0] * m[2][1] * m[3][2]+m[0][0] * m[1][3] * m[2][1] * m[3][2]+
	      m[0][1] * m[1][0] * m[2][3] * m[3][2]-m[0][0] * m[1][1] * m[2][3] * m[3][2]-m[0][2] * m[1][1] * m[2][0] * m[3][3]+m[0][1] * m[1][2] * m[2][0] * m[3][3]+
	      m[0][2] * m[1][0] * m[2][1] * m[3][3]-m[0][0] * m[1][2] * m[2][1] * m[3][3]-m[0][1] * m[1][0] * m[2][2] * m[3][3]+m[0][0] * m[1][1] * m[2][2] * m[3][3];
	   return value;
	   }
	  
	  public float[][] inverseMatrix4D (float[][] m) {
	     float[][] value = new float[4][4];
	   value[0][0] = m[1][2]*m[2][3]*m[3][1] - m[1][3]*m[2][2]*m[3][1] + m[1][3]*m[2][1]*m[3][2] - m[1][1]*m[2][3]*m[3][2] - m[1][2]*m[2][1]*m[3][3] + m[1][1]*m[2][2]*m[3][3];
	   value[0][1] = m[0][3]*m[2][2]*m[3][1] - m[0][2]*m[2][3]*m[3][1] - m[0][3]*m[2][1]*m[3][2] + m[0][1]*m[2][3]*m[3][2] + m[0][2]*m[2][1]*m[3][3] - m[0][1]*m[2][2]*m[3][3];
	   value[0][2] = m[0][2]*m[1][3]*m[3][1] - m[0][3]*m[1][2]*m[3][1] + m[0][3]*m[1][1]*m[3][2] - m[0][1]*m[1][3]*m[3][2] - m[0][2]*m[1][1]*m[3][3] + m[0][1]*m[1][2]*m[3][3];
	   value[0][3] = m[0][3]*m[1][2]*m[2][1] - m[0][2]*m[1][3]*m[2][1] - m[0][3]*m[1][1]*m[2][2] + m[0][1]*m[1][3]*m[2][2] + m[0][2]*m[1][1]*m[2][3] - m[0][1]*m[1][2]*m[2][3];
	   value[1][0] = m[1][3]*m[2][2]*m[3][0] - m[1][2]*m[2][3]*m[3][0] - m[1][3]*m[2][0]*m[3][2] + m[1][0]*m[2][3]*m[3][2] + m[1][2]*m[2][0]*m[3][3] - m[1][0]*m[2][2]*m[3][3];
	   value[1][1] = m[0][2]*m[2][3]*m[3][0] - m[0][3]*m[2][2]*m[3][0] + m[0][3]*m[2][0]*m[3][2] - m[0][0]*m[2][3]*m[3][2] - m[0][2]*m[2][0]*m[3][3] + m[0][0]*m[2][2]*m[3][3];
	   value[1][2] = m[0][3]*m[1][2]*m[3][0] - m[0][2]*m[1][3]*m[3][0] - m[0][3]*m[1][0]*m[3][2] + m[0][0]*m[1][3]*m[3][2] + m[0][2]*m[1][0]*m[3][3] - m[0][0]*m[1][2]*m[3][3];
	   value[1][3] = m[0][2]*m[1][3]*m[2][0] - m[0][3]*m[1][2]*m[2][0] + m[0][3]*m[1][0]*m[2][2] - m[0][0]*m[1][3]*m[2][2] - m[0][2]*m[1][0]*m[2][3] + m[0][0]*m[1][2]*m[2][3];
	   value[2][0] = m[1][1]*m[2][3]*m[3][0] - m[1][3]*m[2][1]*m[3][0] + m[1][3]*m[2][0]*m[3][1] - m[1][0]*m[2][3]*m[3][1] - m[1][1]*m[2][0]*m[3][3] + m[1][0]*m[2][1]*m[3][3];
	   value[2][1] = m[0][3]*m[2][1]*m[3][0] - m[0][1]*m[2][3]*m[3][0] - m[0][3]*m[2][0]*m[3][1] + m[0][0]*m[2][3]*m[3][1] + m[0][1]*m[2][0]*m[3][3] - m[0][0]*m[2][1]*m[3][3];
	   value[2][2] = m[0][1]*m[1][3]*m[3][0] - m[0][3]*m[1][1]*m[3][0] + m[0][3]*m[1][0]*m[3][1] - m[0][0]*m[1][3]*m[3][1] - m[0][1]*m[1][0]*m[3][3] + m[0][0]*m[1][1]*m[3][3];
	   value[2][3] = m[0][3]*m[1][1]*m[2][0] - m[0][1]*m[1][3]*m[2][0] - m[0][3]*m[1][0]*m[2][1] + m[0][0]*m[1][3]*m[2][1] + m[0][1]*m[1][0]*m[2][3] - m[0][0]*m[1][1]*m[2][3];
	   value[3][0] = m[1][2]*m[2][1]*m[3][0] - m[1][1]*m[2][2]*m[3][0] - m[1][2]*m[2][0]*m[3][1] + m[1][0]*m[2][2]*m[3][1] + m[1][1]*m[2][0]*m[3][2] - m[1][0]*m[2][1]*m[3][2];
	   value[3][1] = m[0][1]*m[2][2]*m[3][0] - m[0][2]*m[2][1]*m[3][0] + m[0][2]*m[2][0]*m[3][1] - m[0][0]*m[2][2]*m[3][1] - m[0][1]*m[2][0]*m[3][2] + m[0][0]*m[2][1]*m[3][2];
	   value[3][2] = m[0][2]*m[1][1]*m[3][0] - m[0][1]*m[1][2]*m[3][0] - m[0][2]*m[1][0]*m[3][1] + m[0][0]*m[1][2]*m[3][1] + m[0][1]*m[1][0]*m[3][2] - m[0][0]*m[1][1]*m[3][2];
	   value[3][3] = m[0][1]*m[1][2]*m[2][0] - m[0][2]*m[1][1]*m[2][0] + m[0][2]*m[1][0]*m[2][1] - m[0][0]*m[1][2]*m[2][1] - m[0][1]*m[1][0]*m[2][2] + m[0][0]*m[1][1]*m[2][2];
	   scaleMatrix(value,1f/determinant4D(value));
	   return value;
	}

	  
	  public void scaleMatrix(float[][] m,float s) {
	    for (int i = 0; i < m.length; i++) {
	      for (int j = 0; j < m[0].length; j++) {
	        m[i][j] *= s;
	      
	      }
	    }
	  
	  };
	   
	  
	  public void matrixMultArray (float[][] theInput) {
	    for (int i=0; i < theInput.length; i++) {
	      theInput[i] = matrixMult(theInput[i], transMatrix);
//	      theInput[i] = matrixMult(theInput[i], rotXMatrix);
//	      theInput[i] = matrixMult(theInput[i], rotYMatrix);
//	      theInput[i] = matrixMult(theInput[i], rotZMatrix);
	    }
	  };
	  
	  
	    public void matrixMultArray (float[][] theInput, float[][] theMatrix) {
	    for (int i=0; i < theInput.length; i++) {
	      theInput[i] = matrixMult(theInput[i], theMatrix);
	    }
	  };
	  
	  public float[] matrixMult(float[] v, float[][] m) {
	    v = (float[])PApplet.append(v,0f);
	    float[] retVal = new float[3];
	    retVal[0] = 0f;
	    retVal[1] = 0f;
	    retVal[2] = 0f;
	    for (int i = 0; i < m.length-1; i++) {
	       for (int j = 0; j < m[0].length; j++) {
	          retVal[i] += m[i][j]*v[j];
	      }
	    }
	    return retVal;
	  }
	  
	  public void resetPlane(float thePlaneValue) {
	    planeValue = thePlaneValue;
	    resetArrays();
	    setLines();
	  }

	  public void incPlane(float thePlaneIncValue) {
	    planeValue += thePlaneIncValue;
	    resetArrays();
	    setLines();
	  }


	  public void setLines() {
	    gc_0 = new GridCoordinates(p00,sp00,sp00d,set0_Point,set0_Vec,set0_Shape,0,this);
	    set0_Point = gc_0.getPointArray();
	    set0_Vec = gc_0.getSpacePointArray();
	    set0_Shape = gc_0.getShapeArray();

	    gc_0 = new GridCoordinates(p01,sp01,sp01d,set0_Point,set0_Vec,set0_Shape,1,this);
	    set0_Point = gc_0.getPointArray();
	    set0_Vec = gc_0.getSpacePointArray();
	    set0_Shape = gc_0.getShapeArray();

	    gc_0 = new GridCoordinates(p02,sp02,sp02d,set0_Point,set0_Vec,set0_Shape,2,this);
	    set0_Point = gc_0.getPointArray();
	    set0_Vec = gc_0.getSpacePointArray();
	    set0_Shape = gc_0.getShapeArray();

	    gc_1 = new GridCoordinates(p10,sp10,sp10d,set1_Point,set1_Vec,set1_Shape,0,this);
	    set1_Point = gc_1.getPointArray();
	    set1_Vec = gc_1.getSpacePointArray();
	    set1_Shape = gc_1.getShapeArray();

	    gc_1 = new GridCoordinates(p11,sp11,sp11d,set1_Point,set1_Vec,set1_Shape,1,this);
	    set1_Point = gc_1.getPointArray();
	    set1_Vec = gc_1.getSpacePointArray();
	    set1_Shape = gc_1.getShapeArray();

	    gc_1 = new GridCoordinates(p12,sp12,sp12d,set1_Point,set1_Vec,set1_Shape,2,this);
	    set1_Point = gc_1.getPointArray();
	    set1_Vec = gc_1.getSpacePointArray();
	    set1_Shape = gc_1.getShapeArray();

	    gc_1 = new GridCoordinates(p13,sp13,sp13d,set1_Point,set1_Vec,set1_Shape,3,this);
	    set1_Point = gc_1.getPointArray();
	    set1_Vec = gc_1.getSpacePointArray();
	    set1_Shape = gc_1.getShapeArray();

	    gc_1 = new GridCoordinates(p14,sp14,sp14d,set1_Point,set1_Vec,set1_Shape,4,this);
	    set1_Point = gc_1.getPointArray();
	    set1_Vec = gc_1.getSpacePointArray();
	    set1_Shape = gc_1.getShapeArray();

	    gc_1 = new GridCoordinates(p15,sp15,sp15d,set1_Point,set1_Vec,set1_Shape,5,this);
	    set1_Point = gc_1.getPointArray();
	    set1_Vec = gc_1.getSpacePointArray();
	    set1_Shape = gc_1.getShapeArray();

	    gc_2 = new GridCoordinates(p20,sp20,sp20d,set2_Point,set2_Vec,set2_Shape,0,this);
	    set2_Point = gc_2.getPointArray();
	    set2_Vec = gc_2.getSpacePointArray();
	    set2_Shape = gc_2.getShapeArray();

	    gc_2 = new GridCoordinates(p21,sp21,sp21d,set2_Point,set2_Vec,set2_Shape,1,this);
	    set2_Point = gc_2.getPointArray();
	    set2_Vec = gc_2.getSpacePointArray();
	    set2_Shape = gc_2.getShapeArray();

	    gc_2 = new GridCoordinates(p22,sp22,sp22d,set2_Point,set2_Vec,set2_Shape,2,this);
	    set2_Point = gc_2.getPointArray();
	    set2_Vec = gc_2.getSpacePointArray();
	    set2_Shape = gc_2.getShapeArray();

	    gc_2 = new GridCoordinates(p23,sp23,sp23d,set2_Point,set2_Vec,set2_Shape,3,this);
	    set2_Point = gc_2.getPointArray();
	    set2_Vec = gc_2.getSpacePointArray();
	    set2_Shape = gc_2.getShapeArray();

	    gc_3 = new GridCoordinates(p30,sp30,sp30d,set3_Point,set3_Vec,set3_Shape,0,this);
	    set3_Point = gc_3.getPointArray();
	    set3_Vec = gc_3.getSpacePointArray();
	    set3_Shape = gc_3.getShapeArray();

	    gc_3 = new GridCoordinates(p31,sp31,sp31d,set3_Point,set3_Vec,set3_Shape,1,this);
	    set3_Point = gc_3.getPointArray();
	    set3_Vec = gc_3.getSpacePointArray();
	    set3_Shape = gc_3.getShapeArray();

	    gc_3 = new GridCoordinates(p32,sp32,sp32d,set3_Point,set3_Vec,set3_Shape,2,this);
	    set3_Point = gc_3.getPointArray();
	    set3_Vec = gc_3.getSpacePointArray();
	    set3_Shape = gc_3.getShapeArray();




	    //println(set0_Vec);
	    //println(set1_Vec);
	    //println(set2_Vec);
	    //println(set3_Vec);
	    //    println(set0_Shape);
	     //   println(set1_Shape);
	    //    println(set2_Shape);
	    //    println(set3_Shape);
	        
//	        println(set3_Vec[0]);
	    
	  };

	  public void drawLineInSpace(int setID, int shapeID) {
	    PVector[] vertices;
	    vertices = null;
	    switch(setID) {
	    case 0:
	      if (set0_Shape != null) {
	        for (int i = 0; i < set0_Shape.length; i++) {
	          if (set0_Shape[i] == shapeID) {
	            PVector p = set0_Vec[i];
	            if (vertices == null) {
	              vertices = new PVector[1];
	              vertices[0] = p;
	            } 
	            else {
	              vertices = (PVector[])PApplet.append(vertices,p);
	            }
	          }
	        }
	        //if (vertices != null) drawVertices(vertices);
	      }
	      break;
	    case 1:
	      if (set1_Shape != null) {
	        for (int i = 0; i < set1_Shape.length; i++) {
	          if (set1_Shape[i] == shapeID) {
	            PVector p = set1_Vec[i];
	            if (vertices == null) {
	              vertices = new PVector[1];
	              vertices[0] = p;
	            } 
	            else {
	              vertices = (PVector[])PApplet.append(vertices,p);
	            }
	          }
	        }
	        //if (vertices != null) drawVertices(vertices);
	      }

	      break;
	    case 2:
	      if (set2_Shape != null) {
	        for (int i = 0; i < set2_Shape.length; i++) {
	          if (set2_Shape[i] == shapeID) {
	            PVector p = set2_Vec[i];
	            if (vertices == null) {
	              vertices = new PVector[1];
	              vertices[0] = p;
	            } 
	            else {
	              vertices = (PVector[])PApplet.append(vertices,p);
	            }
	          }
	        }
	       // if (vertices != null) drawVertices(vertices);
	      }

	      break;
	    case 3:
	      if (set3_Shape != null) {
	        for (int i = 0; i < set3_Shape.length; i++) {
	          if (set3_Shape[i] == shapeID) {
	            PVector p = set3_Vec[i];
	            if (vertices == null) {
	              vertices = new PVector[1];
	              vertices[0] = p;
	            } 
	            else {
	              vertices = (PVector[])PApplet.append(vertices,p);
	            }
	          }
	        }
	       // if (vertices != null) drawVertices(vertices);
	      }
	      break;
	    }
	     if (vertices != null) drawVertices(vertices);
	  }



	  public void drawLineInPlane(int setID, int shapeID) {
	    PVector[] vertices;
	    vertices = null;

	    switch(setID) {
	    case 0:
	          if (set0_Shape != null) {
	      for (int i = 0; i < set0_Shape.length; i++) {
	        if (set0_Shape[i] == shapeID) {
	          PVector p = set0_Point[i];
	          if (vertices == null) {
	            vertices = new PVector[1];
	            vertices[0] = p;
	          } 
	          else {
	            vertices = (PVector[])PApplet.append(vertices,p);
	          }
	        }
	      }
	          }
	      break;
	    case 1:
	              if (set1_Shape != null) {
	      for (int i = 0; i < set1_Shape.length; i++) {
	        if (set1_Shape[i] == shapeID) {
	          PVector p = set1_Point[i];
	          if (vertices == null) {
	            vertices = new PVector[1];
	            vertices[0] = p;
	          } 
	          else {
	            vertices = (PVector[])PApplet.append(vertices,p);
	          }
	        }
	      }
	          }
	      break;
	    case 2:
	      if (set2_Shape != null) {
	      for (int i = 0; i < set2_Shape.length; i++) {
	        if (set2_Shape[i] == shapeID) {
	          PVector p = set2_Point[i];
	          if (vertices == null) {
	            vertices = new PVector[1];
	            vertices[0] = p;
	          } 
	          else {
	            vertices = (PVector[])PApplet.append(vertices,p);
	          }
	        }
	      }
	          }
	      break;
	    case 3:
	    if (set3_Shape != null) {
	      for (int i = 0; i < set3_Shape.length; i++) {
	                  
	        if (set3_Shape[i] == shapeID) {
	          PVector p = set3_Point[i];
	          if (vertices == null) {
	            vertices = new PVector[1];
	            vertices[0] = p;
	          } 
	          else {
	            vertices = (PVector[])PApplet.append(vertices,p);
	          }
	        }
	      }

	          }
	      break;
	    }
	     if (vertices != null) drawVertices(vertices);
	  }

	  public void drawVertices(PVector[] v) {
	      for (int i = 0; i < v.length; i+=2) {
	        int j = (i+1)%v.length;
	        parent.beginShape();
	        parent.vertex(v[i].x,v[i].y,v[i].z);
	        parent.vertex(v[j].x,v[j].y,v[j].z);
	        parent.endShape();
	      }

//	    for (int i = 0; i < v.length; i++) {
//	      for (int j = 0; j < v.length; j++) {
//	        if (i != j) {
//	          beginShape();
//	          vertex(v[i].x,v[i].y,v[i].z);
//	          vertex(v[j].x,v[j].y,v[j].z);
//	          endShape();
//	        }
//	      }
//	    }
	  };









	  public void setPlane(char c) {
	    if (c == 'x') plane = 0;
	    if (c == 'y') plane = 1;
	    if (c == 'z') plane = 2;
	  };

	  public void  setBoundaries () {
	    xMin = getBoundary(0,-1);
	    xMax = getBoundary(0,1);
	    yMin = getBoundary(1,-1);
	    yMax = getBoundary(1,1);
	    zMin = getBoundary(2,-1);
	    zMax = getBoundary(2,1);
	    parent.println("xMin: " + xMin);
	    parent.println("xMax: " + xMax);
	    parent.println("yMin: " + yMin);
	    parent.println("yMax: " + yMax);
	    parent.println("zMin: " + zMin);
	    parent.println("zMax: " + zMax);
	  }

	  public void setPointArrays() {
	    p00 =  parent.points00;
	    p01 =  parent.points01;
	    p02 =  parent.points02;
	    p10 =  parent.points10;
	    p11 =  parent.points11;
	    p12 =  parent.points12;
	    p13 =  parent.points13;
	    p14 =  parent.points14;
	    p15 =  parent.points15;
	    p20 =  parent.points20;
	    p21 =  parent.points21;
	    p22 =  parent.points22;
	    p23 =  parent.points23;
	    p30 =  parent.points30;
	    p31 =  parent.points31;
	    p32 =  parent.points32;
	    sp00 =  parent.spacePoints00;
	    sp01 =  parent.spacePoints01;
	    sp02 =  parent.spacePoints02;
	    sp10 =  parent.spacePoints10;
	    sp11 =  parent.spacePoints11;
	    sp12 =  parent.spacePoints12;
	    sp13 =  parent.spacePoints13;
	    sp14 =  parent.spacePoints14;
	    sp15 =  parent.spacePoints15;
	    sp20 =  parent.spacePoints20;
	    sp21 =  parent.spacePoints21;
	    sp22 =  parent.spacePoints22;
	    sp23 =  parent.spacePoints23;
	    sp30 =  parent.spacePoints30;
	    sp31 =  parent.spacePoints31;
	    sp32 =  parent.spacePoints32;
	    sp00d =  parent.spacePoints00;
	    sp01d =  parent.spacePoints01;
	    sp02d =  parent.spacePoints02;
	    sp10d =  parent.spacePoints10;
	    sp11d =  parent.spacePoints11;
	    sp12d =  parent.spacePoints12;
	    sp13d =  parent.spacePoints13;
	    sp14d =  parent.spacePoints14;
	    sp15d =  parent.spacePoints15;
	    sp20d =  parent.spacePoints20;
	    sp21d =  parent.spacePoints21;
	    sp22d =  parent.spacePoints22;
	    sp23d =  parent.spacePoints23;
	    sp30d =  parent.spacePoints30;
	    sp31d =  parent.spacePoints31;
	    sp32d =  parent.spacePoints32;
	  }


	  public float getBoundary(int plane, int theSign) { ////plane: 0 -> x, 1 -> y, 2 -> z
	    float retVal;
	    if (theSign == 1 ) {
	      retVal = PApplet.MAX_FLOAT*(-1);
	    } 
	    else {
	      retVal = PApplet.MAX_FLOAT;
	    }
	    retVal = getArrayMinMax(parent.spacePoints00, plane, retVal, theSign);
	    retVal = getArrayMinMax(parent.spacePoints01, plane, retVal, theSign);
	    retVal = getArrayMinMax(parent.spacePoints02, plane, retVal, theSign);
	    retVal = getArrayMinMax(parent.spacePoints10, plane, retVal, theSign);
	    retVal = getArrayMinMax(parent.spacePoints11, plane, retVal, theSign);
	    retVal = getArrayMinMax(parent.spacePoints12, plane, retVal, theSign);
	    retVal = getArrayMinMax(parent.spacePoints13, plane, retVal, theSign);
	    retVal = getArrayMinMax(parent.spacePoints14, plane, retVal, theSign);
	    retVal = getArrayMinMax(parent.spacePoints15, plane, retVal, theSign);
	    retVal = getArrayMinMax(parent.spacePoints20, plane, retVal, theSign);
	    retVal = getArrayMinMax(parent.spacePoints21, plane, retVal, theSign);
	    retVal = getArrayMinMax(parent.spacePoints22, plane, retVal, theSign);
	    retVal = getArrayMinMax(parent.spacePoints23, plane, retVal, theSign);
	    retVal = getArrayMinMax(parent.spacePoints30, plane, retVal, theSign);
	    retVal = getArrayMinMax(parent.spacePoints31, plane, retVal, theSign);
	    retVal = getArrayMinMax(parent.spacePoints32, plane, retVal, theSign);
	    return retVal;
	  }

	  public float getArrayMinMax (float[][] theArray, int ind, float mmVal, int sign) {
	    float retVal = mmVal;
	    if (sign == 1) {
	      for (int i = 0; i < theArray.length; i++) {
	        if (theArray[i][ind] > retVal) retVal = theArray[i][ind];
	      }
	    } 
	    else {
	      for (int i = 0; i < theArray.length; i++) {
	        if (theArray[i][ind] < retVal) retVal = theArray[i][ind];
	      }
	    }
	    return retVal;
	  }

	  public void resetArrays () {
	    set0_Point = null;
	    set1_Point = null;
	    set2_Point = null;
	    set3_Point = null;
	    set0_Vec = null;
	    set1_Vec = null;
	    set2_Vec = null;
	    set3_Vec = null;
	    set0_Shape = null;
	    set1_Shape = null;
	    set2_Shape = null;
	    set3_Shape = null;
	  }
	};
